package cn.buk.qms.task;

import cn.buk.qms.service.*;
import cn.buk.tms.bill.service.BillCheckService;
import cn.buk.tms.car.service.RentalCarService;
import cn.buk.tms.flight.service.AutoTicketService;
import cn.buk.tms.flight.service.EtermService;
import cn.buk.tms.flight.service.FlightOrderCheckService;
import cn.buk.tms.flight.service.OrderCheckService;
import cn.buk.tms.hotel.service.HotelOrderService;
import cn.buk.common.util.DateUtil;

import cn.buk.tms.vas.service.VasOrderService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;


/**
 * 定时任务
 *
 * @author yfdai
 */
@Profile({"test"})
@Component
public class PnrTaskTest {

  private static final int SERVER_MAIN = 1;
  private static final int SERVER_SECONDARY = 2;
  private static final int SERVER_THIRD = 3;

  private static final Logger logger = LogManager.getLogger(PnrTaskTest.class);

  @Value("${server_id}")
  private int serverId;

  @Value("${owner_enterprise_id}")
  private int ownerId;

  private String getAgentName() {
    return "system-" + serverId;
  }

  private final BillService billService;
  private final BillCheckService billCheckService;
  private final BillAutoTaskService billAutoTaskService;
  private final FlightOrderService flightOrderService;
  private final FlightChangeOrderService changeOrderService;
  private final OrderCheckService orderCheckService;
  private final FlightRefundOrderService refundOrderService;
  private final HotelOrderService hotelOrderService;
  private final RentalCarService rentalCarService;
  private final VasOrderService vasOrderService;
  private final ReportService reportService;
  private final EnterpriseService enterpriseService;
  private final AutoTicketService autoTicketService;
  private final EtermService etermService;
  private final FlightOrderCheckService flightOrderCheckService;

  @Autowired
  public PnrTaskTest(BillService billService,
                     BillCheckService billCheckService,
                     BillAutoTaskService billAutoTaskService,
                     FlightOrderService flightOrderService,
                     FlightChangeOrderService changeOrderService,
                     FlightRefundOrderService refundOrderService,
                     HotelOrderService hotelOrderService,
                     OrderCheckService orderCheckService,
                     VasOrderService vasOrderService,
                     RentalCarService rentalCarService,
                     ReportService reportService,
                     EnterpriseService enterpriseService,
                     AutoTicketService autoTicketService,
                     EtermService etermService,
                     FlightOrderCheckService flightOrderCheckService
                     ) {
    this.billService = billService;
    this.billCheckService = billCheckService;
    this.billAutoTaskService = billAutoTaskService;
    this.flightOrderService = flightOrderService;
    this.changeOrderService = changeOrderService;
    this.refundOrderService = refundOrderService;
    this.hotelOrderService = hotelOrderService;
    this.vasOrderService = vasOrderService;
    this.rentalCarService = rentalCarService;
    this.reportService = reportService;
    this.enterpriseService = enterpriseService;
    this.autoTicketService = autoTicketService;
    this.etermService = etermService;

    this.orderCheckService = orderCheckService;
    this.flightOrderCheckService = flightOrderCheckService;
  }

  /**
   * .
   * 将账单金额记录到企业应付款中
   */
  @Async
  @Scheduled(cron = "0 30 19 * * *")
  public void syncBillInfo2AmountBalance() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    // 将BillInfo(t301)中新来的账单的金额统计到客户应付款中
    billCheckService.syncBillInfo2Balance();

    //        billService.syncBillTicketCount(); // 修改ticket_count
    //        billService.syncBillOp1(); // 修改op1

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.debug("syncBillInfo2AmountBalance elapsed: " + elapse + " ms.");
  }

  @Async
  @Scheduled(cron = "0 0/15 * * * *")
  public void syncBillInfoAirlines() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    billCheckService.syncBillAirlines();
    billCheckService.checkFlightOrderImportedStatus(getAgentName());
  }

  /**
   * 将账单的销账状态反馈到订单中
   */
  @Async
  @Scheduled(cron = "0 0/30 8-22 * * *")
  public void syncBillPaidStatus() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    final int max = 5000;

    billAutoTaskService.autoSyncBillPaid2FlightOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2VasOrder(getAgentName(), max);

    billAutoTaskService.autoSyncBillPaid2RefundOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2ChangeOrder(getAgentName(), max);

    billAutoTaskService.autoSyncBillPaid2HotelOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2TrainOrder(getAgentName(), max);

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.debug("syncBillPaidStatus elapsed: " + elapse + " ms.");
  }

  @Async
  @Scheduled(cron = "0 0/5 22,23 * * *")
  public void updateBillRefundTicketPnrNo() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }
    billService.updateBillRefundTicketPnrNo(getAgentName());
  }


  /**
   * 检查账单中的订单日期.
   */
  @Async
  @Scheduled(cron = "0 30 22 * * *")
  public void autoCheckBillOrderDate() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    billService.autoUpdateBillVas(getAgentName());
  }


  /**
   * 礼拜一早上8点30分统计一次，六个月内未支付金额最多的头10名，按每月
   */
  @Async
  @Scheduled(cron = "0 30 8 * * 1")
  public void autoAlertUnpaidMonthlyStats() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    reportService.autoAlertMonthlyUnpaidTop10();

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.info("autoAlertUnpaidMonthlyStats elapsed: " + elapse + " ms.");
  }

  /**
   * 每30分钟统计是否有订单需要处理
   */
  @Async
  @Scheduled(cron = "0 0 10-18 * * 1-5")
  public void autoAlertHotelOrderStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

//    //酒店订单
//    hotelOrderService.autoAlertHotelOrderStatus();
//
//    trainOrderService.autoAlertTrainOrderStatus();
//
//    //服务订单
//    vasOrderService.autoAlertVasOrderStatus();
//
//    //保险订单
//    vasOrderService.autoAlertInsuranceOrderStatus();
  }


  /**
   * 每天晚上9点3统计一次，3个月内没有账单的客户
   * <p>
   * cron一般是6个部分或是7个部分：如下所示：
   * 1. Seconds （秒）
   * 2. Minutes （分）
   * 3. Hours （时）
   * 4. Day-of-Month （天）
   * 5. Month （月） Month(月) ：可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示；
   * 6. Day-of-Week （周） Day-of-Week(*每周*)*：*可以用数字1-7表示（1 ＝ 星期日）或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示；
   * 7. Year (年 可选字段)
   */
  @Async
  @Scheduled(cron = "0 0 21 * * 1")
  public void autoAlertNoBusinessCustomer() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    reportService.autoAlertNoBusinessCustomer(this.ownerId, 100);

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.info("autoAlertNoBusinessCustomer elapsed: " + elapse + " ms.");
  }

  /**
   * 每天早上0点30分，把机票订单中的乘机人信息导入到Passenger(t601)中
   */
  @Async
  @Scheduled(cron = "0 30 0 * * *")
  public void importPassenger() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      enterpriseService.importPassengers(ownerId);
      enterpriseService.splitPassengerEnglishName(ownerId, getAgentName());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  /**
   * 导入手机号
   * 每天早上0点30分，把机票订单中的乘机人信息导入到Passenger(t601)中
   */
  @Async
  @Scheduled(cron = "0 0/30 * * * *")
  public void importPassengerMobileMobile() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      enterpriseService.importPassengerMobiles(ownerId, getAgentName(), 29 * 60);
    } catch (Exception ignored) {
    }
  }


  /**
   * 清理重复的
   */
  @Async
  @Scheduled(cron = "0 30 6 * * *")
  public void cleanDuplicatePassenger() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }
    enterpriseService.cleanDuplicatePassenger(5);
  }


  /**
   * 将线上订单同步到线下订单进行处理
   */
  @Async
  @Scheduled(cron = "0 0/5 * * * *")
  public void syncFlightOrderOnline2Offline() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    //自动修改火车票账单中psg_count的数值
    billCheckService.autoCheckTrainBillPsgCount(getAgentName());
  }


  /**
   * 每30秒查找一次需要自动BSP出票的
   */
  @Async
  @Scheduled(cron = "0/30 * * * * *")
  public void checkAutoPrintTickets() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    autoTicketService.checkAutoTicketOrder(5, getAgentName());
  }

  /**
   * 检查需要提交到VAAS的第三方订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkVaasOrder() {
    if (serverId != SERVER_THIRD) {
      return;
    }

//    logger.info("checkVaasOrder begin:" );

    try {
      vasOrderService.checkVaasOrders(ownerId, getAgentName());
    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
//    vasOrderService.checkVaasOrders(24, getAgentName());

//    logger.info("checkVaasOrder end." );
  }


  /**
   * 携程国际比价（暂停）
   */
  @Scheduled(cron = "0 * * * * *")
  public void bijiaIntlFare() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

//    intlOwPolicyService.monitorOwPolicy();
//    intlRtPolicyService.monitorRtPolicy();
  }

  @Async
  @Scheduled(cron = "0 0 5 * * *")
  public void refreshCustomerRecency() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    enterpriseService.refreshCustomerRecency();
  }

  @Async
  @Scheduled(cron = "0 0/5 * * * *")
  public void saveBasicData2Redis() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    //把静态数据放到redis中方便微服务调用
    enterpriseService.saveBasicData2Redis();
  }

  @Async
  @Scheduled(cron = "0 * * * * *")
  public void saveBusinessData2Redis() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    //把静态数据放到redis中方便微服务调用
    enterpriseService.saveBusinessData2Redis();
  }

  /**
   * 每30秒查找一次需要自动生成编码和验价的
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkOrderPrice() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    flightOrderCheckService.checkPriceOfFlightOrders(ownerId, getAgentName());
    etermService.checkPriceOfChangeOrders(ownerId, getAgentName());
    hotelOrderService.checkHotelOrderPrice(ownerId, getAgentName());
  }

  /**
   * 每分钟查找一次需要自动分配审批人的订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkOrderNeedApprover() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    flightOrderService.checkFlightOrderNeedApprover(ownerId, getAgentName());
    hotelOrderService.checkHotelOrderNeedApprover(ownerId, getAgentName());
    rentalCarService.checkRentalCarOrderNeedApprover(ownerId, getAgentName());
  }

  /**
   * 每分钟查找一次需要校验是否违反企业差旅规定的订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkOrderMeetPolicy() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    hotelOrderService.checkHotelOrderCityId(ownerId, getAgentName());
    orderCheckService.checkChangeOrderMobile(ownerId, getAgentName());
    orderCheckService.checkRefundOrderMobile(ownerId, getAgentName());

    flightOrderService.checkFlightOrderMeetPolicy(ownerId, getAgentName());
    hotelOrderService.checkHotelOrderMeetPolicy(ownerId, getAgentName());
    rentalCarService.checkRentalCarOrderMeetPolicy(ownerId, getAgentName());
  }

  /**
   * 每分钟查找一次需要需要自动取消的酒店订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkHotelOrderStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      hotelOrderService.checkHotelOrderStatus(ownerId, getAgentName());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }


  /**
   * 每分钟查找一次需要发送通知的酒店订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkHotelOrderNotifyStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      hotelOrderService.checkHotelOrderNotifyStatus(ownerId, getAgentName());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }

  /**
   * 每分钟查找一次需要需要自动取消的机票订单
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void checkFlightOrderStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      flightOrderService.checkFlightOrderStatus(ownerId, getAgentName());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }

  @Async
  @Scheduled(cron = "0 0/5 * * * *")
  public void refreshFlightOrderPnrDetail() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      flightOrderService.refreshFlightOrderPnrDetail(ownerId, getAgentName());

    } catch (Exception ex) {
      logger.error(ex.getMessage());
    }
  }
}
